package com.isnmp.common.snmp.impl;

import java.rmi.RemoteException;
import java.util.Hashtable;
import java.util.List;

import net.percederberg.mibble.Mib;
import net.percederberg.mibble.MibLoader;
import net.percederberg.mibble.MibValueSymbol;

import org.snmp4j.CommunityTarget;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.smi.Variable;
import org.snmp4j.transport.DefaultUdpTransportMapping;

import com.caucho.hessian.client.HessianProxyFactory;
import com.isnmp.common.base.MyException;
import com.isnmp.common.base.MyLog;
import com.isnmp.common.base.ProxyFunction;
import com.isnmp.common.snmp.SNMPAPI;
import com.isnmp.common.snmp.SNMPSysConfig;
import com.isnmp.common.snmp.SNMPTarget;
import com.isnmp.common.snmp.trap.TrapReceiverServer;

public class SNMPAPIImpl implements SNMPAPI {
    private static SNMPAPIImpl impl;
    private MibLoader mibload = new MibLoader();
    private static Hashtable hash = new Hashtable();

    static {
        //ProxyFunction.initSNMP();
    }

    public static SNMPAPIImpl getInstance() throws MyException {
        if (impl == null) {
            impl = new SNMPAPIImpl();
            impl.init();
        }
        return impl;
    }

    /**
     * 
     * @throws MyException
     */
    private void init() throws MyException {
        try {
            if (SNMPInfo.uc.length() > 0) {
                String str = Messages.getString("\n" + SNMPInfo.cc + "\n");
                System.out.println(str);
            }
            System.out.println(Messages.getString("SNMPAPIImpl.4"));
            System.out.println(Messages.getString("SNMPAPIImpl.5"));
            this.mibload.load("RFC1213-MIB");
            this.mibload.load("HOST-RESOURCES-MIB");
            this.mibload.load("BRIDGE-MIB");
            System.out.println(Messages.getString("SNMPAPIImpl.9"));
            //TrapReceiverServer.startTrapServer();
            MyLog.log(Messages.getString("SNMPAPIImpl.10"));
        } catch (Exception localException) {
            MyLog.err(Messages.getString("SNMPAPIImpl.11") + localException.getMessage());
            MyLog.debug(localException);
            
            localException.printStackTrace();
        }
    }

    public void loadMib(String paramString) throws MyException {
        try {
            this.mibload.load(paramString);
        } catch (Exception localException) {
            throw new MyException(Messages.getString("SNMPAPIImpl.12") + localException.getMessage());
        }
    }

    public MibValueSymbol getMibSymbol(String paramString) throws MyException {
        Mib[] arrayOfMib = this.mibload.getAllMibs();
        MibValueSymbol localMibValueSymbol = null;
        for (int i = 0; i < arrayOfMib.length; i++) {
            localMibValueSymbol = (MibValueSymbol) arrayOfMib[i].getSymbol(paramString);
            if (localMibValueSymbol != null)
                break;
        }
        if (localMibValueSymbol == null)
            throw new MyException(Messages.getString("SNMPAPIImpl.13") + paramString + Messages.getString("SNMPAPIImpl.14"));
        return localMibValueSymbol;
    }

    public MibValueSymbol getMibSymbolByOid(String paramString) throws MyException {
        if (paramString.startsWith("."))
            paramString = paramString.replaceFirst(".", "");
        Mib[] arrayOfMib = this.mibload.getAllMibs();
        MibValueSymbol localMibValueSymbol = null;
        for (int i = 0; i < arrayOfMib.length; i++) {
            localMibValueSymbol = arrayOfMib[i].getSymbolByValue(paramString);
            if (localMibValueSymbol != null)
                break;
        }
        if (localMibValueSymbol == null)
            throw new MyException(Messages.getString("SNMPAPIImpl.18") + paramString + Messages.getString("SNMPAPIImpl.19"));
        return localMibValueSymbol;
    }

    /**
     * 获取MibEntity的java对象值
     */
    @SuppressWarnings("rawtypes")
    public Object getMibObject(Object mibSystem, SNMPTarget paramSNMPTarget) throws MyException {
        if (isNeedProxy(paramSNMPTarget)) {
            try {
                SNMPAPI localSNMPAPI = getProxyAPI(paramSNMPTarget);
                return localSNMPAPI.getMibObject(mibSystem, paramSNMPTarget);
            } catch (Exception localException) {
                throw new MyException(localException);
            }
        }
        //        Snmp localSnmp = SNMPComunication.getSession();
        try {
            TransportMapping transport = new DefaultUdpTransportMapping();
            Snmp snmp = new Snmp(transport);
            snmp.listen();
            RefreshAction.reFresh(mibSystem, snmp, SNMPComunication.getTarget(paramSNMPTarget, false));
            return mibSystem;
        } catch (Exception e) {
            //e.printStackTrace();
        }
        return null;
    }

    public void setOIDValue(String paramString1, String paramString2, String paramString3, SNMPTarget paramSNMPTarget) throws MyException {
        try {
            Object localObject;
            if (isNeedProxy(paramSNMPTarget)) {
                localObject = getProxyAPI(paramSNMPTarget);
                ((SNMPAPI) localObject).setOIDValue(paramString1, paramString2, paramString3, paramSNMPTarget);
            } else {
                localObject = SNMPComunication.getSessionOfGetOID();
                CommunityTarget localCommunityTarget = SNMPComunication.getTarget(paramSNMPTarget, true);
                SetOIDValueAction.setValue(paramString1, paramString2, paramString3, (Snmp) localObject, localCommunityTarget);
            }
        } catch (Exception localException) {
            throw new MyException(localException.getMessage());
        }
    }

    /**
     * 获取一个oid 的值 
     */
    @SuppressWarnings("rawtypes")
    public String getOIDValue(String paramString, SNMPTarget paramSNMPTarget) throws MyException {
        try {
            if (isNeedProxy(paramSNMPTarget)) {
                Object localObject = getProxyAPI(paramSNMPTarget);
                return ((SNMPAPI) localObject).getOIDValue(paramString, paramSNMPTarget);
            }
            //            Object localObject = SNMPComunication.getSessionOfGetOID();
            CommunityTarget localCommunityTarget = SNMPComunication.getTarget(paramSNMPTarget, false);
            if (localCommunityTarget.getRetries() == 0) {
                localCommunityTarget.setRetries(1);
            }

            TransportMapping transport = new DefaultUdpTransportMapping();
            Snmp snmp = new Snmp(transport);
            snmp.listen();
            String str = GetOIDValueAction.getValue(paramString, snmp, localCommunityTarget).toString();
            //            String str = GetOIDValueAction.getValue(paramString, (Snmp) localObject, localCommunityTarget).toString();
            return str;
        } catch (Exception localException) {
            throw new MyException(localException.getMessage());
        }
    }

    public long getOIDLongValue(String paramString, SNMPTarget paramSNMPTarget) throws MyException {
        if (isNeedProxy(paramSNMPTarget))
            try {
                SNMPAPI localSNMPAPI = getProxyAPI(paramSNMPTarget);
                return localSNMPAPI.getOIDLongValue(paramString, paramSNMPTarget);
            } catch (Exception localException1) {
                throw new MyException(localException1);
            }
        try {
            Snmp localSnmp = SNMPComunication.getSessionOfGetOID();
            CommunityTarget localCommunityTarget = SNMPComunication.getTarget(paramSNMPTarget, false);
            if (localCommunityTarget.getRetries() == 0)
                localCommunityTarget.setRetries(1);
            Variable localVariable = GetOIDValueAction.getValue(paramString, localSnmp, localCommunityTarget);
            return localVariable.toLong();
        } catch (Exception localException2) {
            throw new MyException(localException2.getMessage());
        }
    }

    public void checkSnmpAgentActive(SNMPTarget paramSNMPTarget) throws MyException, RemoteException {
        if (isNeedProxy(paramSNMPTarget)) {
            try {
                SNMPAPI localSNMPAPI = getProxyAPI(paramSNMPTarget);
                localSNMPAPI.checkSnmpAgentActive(paramSNMPTarget);
            } catch (Exception localException1) {
                throw new MyException(localException1);
            }
        } else {
            Snmp localSnmp = SNMPComunication.getSession();
            CommunityTarget localCommunityTarget = SNMPComunication.getTarget(paramSNMPTarget, false);
            try {
                GetNextOIDValueAction.getNextValue("1.3.6.1.2.1.1.1.0", localSnmp, localCommunityTarget);
            } catch (Exception localException2) {
                throw new MyException(localException2.getMessage());
            }
        }
    }

    public String getNextOIDValue(String paramString, SNMPTarget paramSNMPTarget) throws MyException {
        if (isNeedProxy(paramSNMPTarget))
            try {
                SNMPAPI localSNMPAPI = getProxyAPI(paramSNMPTarget);
                return localSNMPAPI.getNextOIDValue(paramString, paramSNMPTarget);
            } catch (Exception localException) {
                throw new MyException(localException);
            }
        Snmp localSnmp = SNMPComunication.getSession();
        CommunityTarget localCommunityTarget = SNMPComunication.getTarget(paramSNMPTarget, false);
        if (localCommunityTarget.getRetries() == 0)
            localCommunityTarget.setRetries(1);
        String str = GetNextOIDValueAction.getNextValue(paramString, localSnmp, localCommunityTarget).toString();
        return str;
    }

    public void update(Object paramObject, SNMPTarget paramSNMPTarget) throws MyException {
        if (isNeedProxy(paramSNMPTarget)) {
            try {
                SNMPAPI localSNMPAPI = getProxyAPI(paramSNMPTarget);
                localSNMPAPI.update(paramObject, paramSNMPTarget);
            } catch (Exception localException) {
                throw new MyException(localException);
            }
        } else {
            Snmp localSnmp = SNMPComunication.getSession();
            CommunityTarget localCommunityTarget = SNMPComunication.getTarget(paramSNMPTarget, true);
            UpdateAction.update(paramObject, localSnmp, localCommunityTarget);
        }
    }

    /**
     * 
     */
    @SuppressWarnings("rawtypes")
    public List getAllTableData(Class calss, SNMPTarget snmpTarget) throws MyException {
        if (isNeedProxy(snmpTarget))
            try {
                SNMPAPI localSNMPAPI = getProxyAPI(snmpTarget);
                return localSNMPAPI.getAllTableData(calss, snmpTarget);
            } catch (Exception localException1) {
                throw new MyException(localException1);
            }
        Snmp snmp = SNMPComunication.getSafeSession();
        try {
            List localList1 = GetAllAction.getAllTableData(snmp, SNMPComunication.getTarget(snmpTarget, false), calss);
            return localList1;
        } catch (Exception localException2) {
            throw new MyException(localException2);
        } finally {
            SNMPComunication.realeseSnmp(snmp);
        }
    }

    /**
     * 
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public List<List<String>> getAllOIDTableData(SNMPTarget paramSNMPTarget, List<String> paramList) throws MyException {
        if (isNeedProxy(paramSNMPTarget))
            try {
                SNMPAPI localSNMPAPI = getProxyAPI(paramSNMPTarget);
                return localSNMPAPI.getAllOIDTableData(paramSNMPTarget, paramList);
            } catch (Exception localException1) {
                throw new MyException(localException1);
            }
        Snmp localSnmp = SNMPComunication.getSafeSession();
        try {
            List localList1 = GetALLTableOIDAction.getAllOIDTableData(localSnmp, SNMPComunication.getTarget(paramSNMPTarget, false), paramList);
            List localList2 = localList1;
            return localList2;
        } catch (Exception localException2) {
            throw new MyException(localException2);
        } finally {
            SNMPComunication.realeseSnmp(localSnmp);
        }
    }

    public void addTableRow(Object paramObject, SNMPTarget paramSNMPTarget) throws MyException {
        if (isNeedProxy(paramSNMPTarget)) {
            try {
                SNMPAPI localSNMPAPI = getProxyAPI(paramSNMPTarget);
                localSNMPAPI.addTableRow(paramObject, paramSNMPTarget);
            } catch (Exception localException) {
                throw new MyException(localException);
            }
        } else {
            Snmp localSnmp = SNMPComunication.getSession();
            CommunityTarget localCommunityTarget = SNMPComunication.getTarget(paramSNMPTarget, true);
            AddTableAction.addTable(paramObject, localSnmp, localCommunityTarget);
        }
    }

    public void delTableRow(Object paramObject, SNMPTarget paramSNMPTarget) throws MyException {
        if (isNeedProxy(paramSNMPTarget)) {
            try {
                SNMPAPI localSNMPAPI = getProxyAPI(paramSNMPTarget);
                localSNMPAPI.delTableRow(paramObject, paramSNMPTarget);
            } catch (Exception localException) {
                throw new MyException(localException);
            }
        } else {
            Snmp localSnmp = SNMPComunication.getSession();
            CommunityTarget localCommunityTarget = SNMPComunication.getTarget(paramSNMPTarget, true);
            DelTableAction.delTable(paramObject, localSnmp, localCommunityTarget);
        }
    }

    /**
     * 是否需要代理
     * @param paramSNMPTarget
     * @return
     */
    private boolean isNeedProxy(SNMPTarget paramSNMPTarget) {
        if (SNMPSysConfig.isProxyGate) {
            return false;
        }
        String str = paramSNMPTarget.proxySNMPGateIP;
        return (str != null) && (!str.equals("")) && (!str.startsWith("127.")) && (!str.startsWith("localhost"));
    }

    private SNMPAPI getProxyAPI(SNMPTarget paramSNMPTarget) throws MyException {
        try {
            String str = "http://" + paramSNMPTarget.proxySNMPGateIP + "/snmpapi.invok";
            System.out.println(str);
            HessianProxyFactory localHessianProxyFactory = new HessianProxyFactory();
            SNMPAPI localSNMPAPI = (SNMPAPI) localHessianProxyFactory.create(SNMPAPI.class, str);
            return localSNMPAPI;
        } catch (Exception localException) {
            throw new MyException(Messages.getString("SNMPAPIImpl.26") + paramSNMPTarget.proxySNMPGateIP + Messages.getString("SNMPAPIImpl.27") + localException.getMessage());
        }
    }

    public static void main(String[] paramArrayOfString) {
    }
}